﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using iTunesLib;
using System.IO;

namespace iTunesUpdater
{
	public partial class MainWindow : Form
	{
		TimeSpan addInterval = new TimeSpan(0, 10, 0);
		TimeSpan deleteInterval = new TimeSpan(12, 0, 0);
		TimeSpan transcodeInterval = new TimeSpan(0, 10, 0);
		DateTime nextAdd = DateTime.Now;
		DateTime nextDelete = DateTime.Now;
		DateTime nextTranscode = DateTime.Now;

		Transcoder transcoder = new Transcoder();

		public MainWindow() {
			InitializeComponent();
		}

		private void timer1_Tick(object sender, EventArgs e) {
			if (DateTime.Now >= nextAdd && cbAddnew.Checked)
				AddNow();
			if (DateTime.Now >= nextDelete && cbKillDead.Checked)
				KillDeadNow();
			if (DateTime.Now >= nextTranscode && cbTranscode.Checked) {
				TranscodeAll();
			}

			TimeSpan ts = new TimeSpan(0);
			if (cbTranscode.Checked)
				ts = nextTranscode - DateTime.Now;
			else if (cbAddnew.Checked)
				ts = nextAdd - DateTime.Now;
			else if (cbKillDead.Checked)
				ts = nextDelete - DateTime.Now;

			lTimer.Text =
				ts.Hours.ToString("00") + ":"
				+ ts.Minutes.ToString("00") + ":"
				+ ts.Seconds.ToString("00");

		}

		private void TranscodeAll() {
			transcoder.TranscodeAll();
			nextTranscode = DateTime.Now + transcodeInterval;
		}

		private void bScan_Click(object sender, EventArgs e) {
			if (cbAddnew.Checked) AddNow();
			if (cbKillDead.Checked) KillDeadNow();
			if (cbTranscode.Checked) TranscodeAll();
		}

		private void AddNow() {
			bScan.Enabled = false;
			timer1.Enabled = false;
			AddNewTracks();
			nextAdd = DateTime.Now + addInterval;
			timer1.Enabled = true;
			bScan.Enabled = true;
		}

		private void KillDeadNow() {
			bScan.Enabled = false;
			timer1.Enabled = false;
			RemoveDeadTracks();
			nextDelete = DateTime.Now + deleteInterval;
			timer1.Enabled = true;
			bScan.Enabled = true;
		}

		SortedList<string, string> TrackList = new SortedList<string, string>();
		void ReadTrackList() {
			if (TrackList.Count == 0) {
				RemoveDeadTracks();
			}
		}

		public void RemoveDeadTracks() {
			try {
				TrackList.Clear();
				iTunesLib.iTunesApp iTunes = new iTunesLib.iTunesApp();
				int deletedTracks = 0;

				IITTrackCollection tracks = iTunes.LibraryPlaylist.Tracks;
				int numTracks = tracks.Count;
				progressBar2.Value = 0;
				progressBar2.Maximum = numTracks;

				while (numTracks > 0) {
					iTunesLib.IITTrack currTrack = tracks[numTracks];

					// is this a file track?
					if (currTrack.Kind == iTunesLib.ITTrackKind.ITTrackKindFile) {
						iTunesLib.IITFileOrCDTrack track = (iTunesLib.IITFileOrCDTrack)currTrack;
						// yes, does it have an empty location?
						if (!System.IO.File.Exists(track.Location)) {
							log.Write("Removed " + currTrack.Name + "\r\n");
							// yes, delete it
							currTrack.Delete();
							deletedTracks++;
						}
						else if (!TrackList.ContainsKey(track.Location))
							TrackList.Add(track.Location, track.Name);
					}

					numTracks--;
					progressBar2.Value = numTracks;
					lTimer.Text = numTracks.ToString();
					Application.DoEvents();
				}

			}
			catch (Exception ex) {
				MessageBox.Show("Cannot remove dead tracks.\r\n" + ex.Message);
			}

		}

		iTunesLib.IITOperationStatus AddStatus;
		List<string> NewFiles = new List<string>();
		public void AddNewTracks() {
			TitleScanner scanner = new TitleScanner(ucItemList1.Items);
			try {
				iTunesLib.iTunesApp iTunes = new iTunesLib.iTunesApp();

				int i;
				System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(tbDest.Text);
				System.IO.FileInfo[] files = dir.GetFiles("*.mp4", System.IO.SearchOption.AllDirectories);
				iTunesLib.IITLibraryPlaylist mainLibrary = iTunes.LibraryPlaylist;

				progressBar2.Value = 0;
				progressBar2.Maximum = files.Length;

				for (i = 0; i < files.Length; i++) {
					System.IO.FileInfo file = files[i];
					progressBar2.Value = i;
					lTimer.Text = i.ToString() + "/" + files.Length.ToString();
					Application.DoEvents();

					string ext = System.IO.Path.GetExtension(file.FullName).ToLower();
					TrackInfo info = scanner.GetTrackInfo(file.Name);
					IITTrack foundTrack = mainLibrary.Tracks.get_ItemByName(info.Name);
					if (foundTrack == null && (Transcoder.CurrentFile != file.FullName)) {
						log.Write("Adding " + file.Name + "...");
						AddStatus = iTunes.LibraryPlaylist.AddFile(file.FullName);
						if (AddStatus != null) {
							iTunesLib.IITFileOrCDTrack track = (iTunesLib.IITFileOrCDTrack)AddStatus.Tracks[1];
							track.VideoKind = ITVideoKind.ITVideoKindTVShow;
							track.Show = info.ShowName;
							track.Name = info.Name;
						}
						log.Write("done.\r\n");
					}
				}
				progressBar2.Value = progressBar2.Maximum;
			}
			catch (Exception ex) {
				MessageBox.Show(this, "Can't scan for new files.\r\n" + ex.Message, "Scan Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
		}

		private void Form1_Load(object sender, EventArgs e) {
			tbDest.Text = iTunesUpdater.Properties.Settings.Default.MediaPath;
			tbSource.Text = Properties.Settings.Default.SourcePath;
			tbFilter.Text = Properties.Settings.Default.Filter;
			nextAdd = DateTime.Now.AddSeconds(30);
			nextDelete = DateTime.Now.AddSeconds(30);
			cbAddnew.Checked = Properties.Settings.Default.AddEnabled;
			cbKillDead.Checked = Properties.Settings.Default.RemoveEnabled;
			cbTranscode.Checked = Properties.Settings.Default.TranscodeEnabled;

			transcoder.logMessage += new Transcoder.LogEvent(transcoder_logMessage);

      SetDestFolder();
      SetSourceFolders();

			nextAdd = DateTime.Now.AddMinutes(1);
			nextDelete = DateTime.Now.AddMinutes(2);
			nextTranscode = DateTime.Now.AddMinutes(3);

			timer1.Enabled = true;
		}

		void transcoder_logMessage(Transcoder sender, string message) {
			log.WriteLine(message);
		}

		private void SetDestFolder() {
			Transcoder.Destpath = tbDest.Text;
			DestFileList.WatchFolders = tbDest.Text;
			DestFileList.Extensions = "*.mp4;*.m4v";
			DestFileList.UseGroups = false;
			try {
				DestFileList.StartWatching();
				log.WriteLine("Watching dest: " + tbDest.Text);
				timer1.Enabled = true;
			}
			catch (Exception ex) {
				log.WriteLine("Please check destination folders!\r\n" + ex.Message);
				timer1.Enabled = false;
			}
		}

		private void SetSourceFolders() {
			Transcoder.SourcePath = tbSource.Text;
			Transcoder.SourceFilter = tbFilter.Text;
			SourceFileList.WatchFolders = tbSource.Text;
			SourceFileList.Extensions = tbFilter.Text;
			SourceFileList.UseGroups = true;
			try {
				SourceFileList.StartWatching();
				log.WriteLine("Watching source: " + tbSource.Text);
			}
			catch (Exception ex) {
				log.WriteLine("Please check source folders!\r\n" + ex.Message);
			}
		}

		private void bSetPath_Click(object sender, EventArgs e) {
			FolderBrowserDialog d = new FolderBrowserDialog();
			try {
				d.SelectedPath = tbDest.Text;
			}
			catch {
			}

			if (d.ShowDialog() == DialogResult.OK) {
				tbDest.Text = d.SelectedPath;
				SetDestFolder();
			}
		}

		private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
			Properties.Settings.Default.MediaPath = tbDest.Text;
			Properties.Settings.Default.SourcePath = tbSource.Text;
			Properties.Settings.Default.AddEnabled = cbAddnew.Checked;
			Properties.Settings.Default.RemoveEnabled = cbKillDead.Checked;
			Properties.Settings.Default.TranscodeEnabled = cbTranscode.Checked;
			Properties.Settings.Default.Filter = tbFilter.Text;

			Properties.Settings.Default.Filters.Clear();
			foreach (string filter in ucItemList1.Items) {
				Properties.Settings.Default.Filters.Add(filter);
			}
			Properties.Settings.Default.Save();
		}

		private void ucItemList1_Load(object sender, EventArgs e) {
			ucItemList1.PromptText = "Enter filter definition:"
				+ "\r\n<s> - Show Name"
				+ "\r\n<e> - Episode"
				+ "\r\n<x>,<n> - Part Number (x/n)"
				+ "\r\n<y>,<m>,<d> - Air Date Year, month, day"
				+ "\r\n";
			ucItemList1.PromptTitle = "Edit Filter Definition";

			ucItemList1.Items.Clear();
			foreach (string filter in Properties.Settings.Default.Filters) {
				ucItemList1.Items.Add(filter);
			}
		}

		private void button1_Click(object sender, EventArgs e) {
			TitleScanner scanner = new TitleScanner(ucItemList1.Items);

			foreach (string path in tbSource.Text.Split(';')) {
				string[] files = System.IO.Directory.GetFiles(path, "*.mpg", System.IO.SearchOption.AllDirectories);
				foreach (string file in files) {
					TrackInfo t = scanner.GetTrackInfo(file);
					log.Write(
						"File: " + System.IO.Path.GetFileName(file)
						+ "\r\n  Show: " + t.ShowName
						+ "\r\n  Episode: " + t.Name
						+ "\r\n  Date: " + t.Month + "/" + t.Day + "/" + t.Year
						+ "\r\n-----------------------------------------------"
						+ "\r\n");
				}
			}

		}

		private void bKill_Click(object sender, EventArgs e) {
			KillDeadNow();
		}

		private void bAddTracks_Click(object sender, EventArgs e) {
			AddNow();
		}

		private void button3_Click(object sender, EventArgs e) {
			FolderBrowserDialog d = new FolderBrowserDialog();
			try {
				d.SelectedPath = tbSource.Text;
			}
			catch {
			}

			if (d.ShowDialog() == DialogResult.OK) {
				tbSource.Text = d.SelectedPath;
				SetSourceFolders();
			}
		}

		private void bTranscode_Click(object sender, EventArgs e) {
			if (Transcoder.isTranscodeActive) {
				if (MessageBox.Show(null, "A transcode may be in progress. Reset transcode flag?", "Start Transcode", MessageBoxButtons.YesNo) == DialogResult.Yes) {
					Transcoder.SetTranscodeFinished();
				}
			}
			TranscodeAll();
		}

		private void tbSource_Validated(object sender, EventArgs e) {
			SetSourceFolders();
		}

		private void tbDest_Validated(object sender, EventArgs e) {
			SetDestFolder();
		}

		private void encodeToolStripMenuItem_Click(object sender, EventArgs e) {

		}

		private void deleteToolStripMenuItem_Click(object sender, EventArgs e) {
			SourceFileList.DeleteSelectedItems();
		}

		private void tbFilter_Validated(object sender, EventArgs e) {
			SetSourceFolders();
		}

		private void deleteToolStripMenuItem1_Click(object sender, EventArgs e) {
			DestFileList.DeleteSelectedItems();
		}

	}
}
